/**
 * @Author: ls-mac
 * @Date:   2018-10-11T15:53:33+08:00
 * @Last modified by:   ls-mac
 * @Last modified time: 2020-07-16 15:24:47
 */

import React, { PureComponent, Fragment } from 'react';
import PropTypes from 'prop-types';
import { Layout, Form, Row, Col, Modal, message, Input, Icon, Tabs } from 'antd';
import DocumentTitle from 'react-document-title';
import { connect } from 'dva';
import { Route, Redirect, Switch, routerRedux } from 'dva/router';

import { ContainerQuery } from 'react-container-query';
import classNames from 'classnames';
import pathToRegexp from 'path-to-regexp';
import { enquireScreen, unenquireScreen } from 'enquire-js';
import GlobalHeader from 'components/GlobalHeader';
import GlobalFooter from 'components/GlobalFooter';
import SiderMenu from 'components/SiderMenu';
import { getRoutes } from 'utils/utils';
import Authorized from 'utils/Authorized';
import logo from 'assets/logo.png';
import transparentP from 'assets/transparent.png';
import errorMsg from 'utils/error';
import { getMenuData } from '../common/menu';
import NotFound from '../routes/Exception/404';

const { Content, Header, Footer } = Layout;
const { AuthorizedRoute, check } = Authorized;
const FormItem = Form.Item;
const { TabPane } = Tabs;

/**
 * 根据菜单取得重定向地址.
 */
const redirectData = [];
const getRedirect = item => {
  if (item && item.children) {
    if (item.children[0] && item.children[0].path) {
      redirectData.push({
        from: `${item.path}`,
        to: `${item.children[0].path}`,
      });
      item.children.forEach(children => {
        getRedirect(children);
      });
    }
  }
};
getMenuData().forEach(getRedirect);

/**
 * 获取面包屑映射
 * @param {Object} menuData 菜单配置
 * @param {Object} routerData 路由配置
 */
const getBreadcrumbNameMap = (menuData, routerData) => {
  const result = {};
  const childResult = {};
  for (const i of menuData) {
    if (!routerData[i.path]) {
      result[i.path] = i;
    }
    if (i.children) {
      Object.assign(childResult, getBreadcrumbNameMap(i.children, routerData));
    }
  }
  return Object.assign({}, routerData, result, childResult);
};

const query = {
  'screen-xs': {
    maxWidth: 575,
  },
  'screen-sm': {
    minWidth: 576,
    maxWidth: 767,
  },
  'screen-md': {
    minWidth: 768,
    maxWidth: 991,
  },
  'screen-lg': {
    minWidth: 992,
    maxWidth: 1199,
  },
  'screen-xl': {
    minWidth: 1200,
    maxWidth: 1599,
  },
  'screen-xxl': {
    minWidth: 1600,
  },
};

@connect(({ global, login, loading }) => ({
  login,
  global,
}))
export default class BasicLayout extends PureComponent {
  static childContextTypes = {
    location: PropTypes.object,
    breadcrumbNameMap: PropTypes.object,
  };

  constructor(props) {
    super(props);
  }

  state = {
    showPwd: false,
  };

  hidePwdModal = () => {
    this.setState({ showPwd: false });
  };

  showPwdModal = () => {
    this.setState({ showPwd: true });
  };

  changePwd = record => {
    const { dispatch } = this.props;
    dispatch({
      type: 'global/changePwd',
      payload: record,
      callback: resp => {
        if (resp && resp.success) {
          message.info('修改密码成功');
          this.setState({ showPwd: false });
        } else {
          errorMsg(resp);
        }
      },
    });
  };

  getChildContext() {
    const { location, routerData } = this.props;
    return {
      location,
      breadcrumbNameMap: getBreadcrumbNameMap(getMenuData(), routerData),
    };
  }

  componentDidMount() {
    const { dispatch } = this.props;
    if (!localStorage.getItem('currentUser')) {
      dispatch(
        routerRedux.push({
          pathname: '/',
        })
      );
    }
  }

  componentWillUnmount() {}

  getPageTitle() {
    const { routerData, location } = this.props;
    const { pathname } = location;
    let title = '郦森健康管理平台';
    let currRouterData = null;
    // match params path
    Object.keys(routerData).forEach(key => {
      if (pathToRegexp(key).test(pathname)) {
        currRouterData = routerData[key];
      }
    });
    if (currRouterData && currRouterData.name) {
      title = `${currRouterData.name} - 郦森健康管理平台`;
    }
    return title;
  }

  onChange = k => {
    const {
      dispatch,
      global: { panes, activeKey, collapsed },
    } = this.props;
    dispatch({
      type: 'global/changeActiveKey',
      payload: k,
    });
    dispatch(
      routerRedux.push({
        pathname: panes[k],
      })
    );
  };

  onEdit = k => {
    const {
      dispatch,
      global: { panes, activeKey },
    } = this.props;

    let newIndex = 0;

    if (k - 0 > activeKey - 0) {
      newIndex = activeKey;
    }
    if (k - 0 == activeKey - 0) {
      newIndex = k - 0 == panes.length - 1 ? activeKey - 1 : activeKey - 0 + 1;
    }
    if (k - 0 < activeKey - 0) {
      newIndex = activeKey;
    }

    dispatch({
      type: 'global/deleteActiveKey',
      payload: k,
    });
    dispatch(
      routerRedux.push({
        pathname: panes[newIndex],
      })
    );
  };

  getBaseRedirect = () => {
    // According to the url parameter to redirect
    // 这里是重定向的,重定向到 url 的 redirect 参数所示地址
    const urlParams = new URL(window.location.href);

    const redirect = urlParams.searchParams.get('redirect');
    // Remove the parameters in the url
    if (redirect) {
      urlParams.searchParams.delete('redirect');
      window.history.replaceState(null, 'redirect', urlParams.href);
    } else {
      const { routerData } = this.props;
      // get the first authorized route path in routerData
      const authorizedPath = Object.keys(routerData).find(
        item => check(routerData[item].authority, item) && item !== '/'
      );
      return authorizedPath;
    }
    return redirect;
  };

  handleMenuCollapse = collapsed => {
    const { dispatch } = this.props;
    dispatch({
      type: 'global/changeLayoutCollapsed',
      payload: collapsed,
    });
  };

  handleNoticeClear = type => {
    message.success(`清空了${type}`);
    const { dispatch } = this.props;
    dispatch({
      type: 'global/clearNotices',
      payload: type,
    });
  };

  handleMenuClick = ({ key }) => {
    const { dispatch } = this.props;
    if (key === 'triggerError') {
      dispatch(routerRedux.push('/exception/trigger'));
      return;
    }
    if (key === 'logout') {
      dispatch({
        type: 'login/logout',
      });
      return;
    }
    if (key === 'changepwd') {
      this.showPwdModal();
    }
  };

  handleNoticeVisibleChange = visible => {
    const { dispatch } = this.props;
    if (visible) {
      dispatch({
        type: 'global/fetchNotices',
      });
    }
  };

  render() {
    const {
      routerData,
      match,
      location,
      login: { currentUser },
      global: { panes, activeKey, collapsed },
      children,
    } = this.props;

    let listP = panes.map((e, i) => {
      //console.log(getRoutes(e, routerData));
      return { name: routerData[e].name, key: i, component: routerData[e].component };
    });

    const { showPwd } = this.state;
    const baseRedirect = this.getBaseRedirect();

    const _backgroundColor = window.location.href.indexOf('welcome') == '-1' ? '#fff' : '#f2f2f2';

    const layout = (
      <Layout style={{ width: '100%', marginLeft: 'auto', marginRight: 'auto' }}>
        <SiderMenu
          logo={logo}
          // 不带Authorized参数的情况下如果没有权限,会强制跳到403界面
          // If you do not have the Authorized parameter
          // you will be forced to jump to the 403 interface without permission
          Authorized={Authorized}
          menuData={getMenuData()}
          collapsed={collapsed}
          location={location}
          onCollapse={this.handleMenuCollapse}
        />
        <Layout style={{ background: '#f2f2f2' }}>
          <Header
            style={{ padding: 0, position: 'fixed', left: 0, top: 0, width: '100%', zIndex: '12' }}
          >
            <GlobalHeader
              logo={logo}
              currentUser={currentUser}
              collapsed={collapsed}
              onCollapse={this.handleMenuCollapse}
              onMenuClick={this.handleMenuClick}
              onNoticeVisibleChange={this.handleNoticeVisibleChange}
              showPwdModal={this.showPwdModal}
            />
          </Header>
          {/* <Content
            style={{
              height: '100%',
              marginLeft: '170px',
              marginTop: '76px',
              minHeight: '60%',
              background: _backgroundColor,
            }}
          >
             <Tabs
              hideAdd
              onChange={this.onChange}
              activeKey={`${activeKey}`}
              type="editable-card"
              onEdit={this.onEdit}
            >
              {listP.map((pane, index) => (
                <TabPane tab={pane.name} key={pane.key}>
                  <Switch>
                    {redirectData.map(item => (
                      <Redirect key={item.from} exact from={item.from} to={item.to} />
                    ))}
                    {getRoutes(match.path, routerData).map(item => (
                      <AuthorizedRoute
                        key={item.key}
                        path={item.path}
                        component={item.component}
                        exact={item.exact}
                        authority={item.authority}
                        redirectPath="/exception/403"
                      />
                    ))}
                    <Redirect exact from="/" to={baseRedirect} />
                    <Route render={NotFound} />
                  </Switch>
                </TabPane>
              ))}
            </Tabs>

            {showPwd ? (
              <ModifyPassword
                changePwd={this.changePwd}
                hidePwdModal={this.hidePwdModal}
                showPwd={showPwd}
              />
            ) : (
              ''
            )}
          </Content> */}
          <Content
            style={{
              height: '100%',
              marginLeft: '170px',
              marginTop: '76px',
              minHeight: '60%',
              background: _backgroundColor,
            }}
          >
            <Switch>
              {redirectData.map(item => (
                <Redirect key={item.from} exact from={item.from} to={item.to} />
              ))}
              {getRoutes(match.path, routerData).map(item => (
                <AuthorizedRoute
                  key={item.key}
                  path={item.path}
                  component={item.component}
                  exact={item.exact}
                  authority={item.authority}
                  redirectPath="/exception/403"
                />
              ))}
              <Redirect exact from="/" to={baseRedirect} />
              <Route render={NotFound} />
            </Switch>
            {showPwd ? (
              <ModifyPassword
                changePwd={this.changePwd}
                hidePwdModal={this.hidePwdModal}
                showPwd={showPwd}
              />
            ) : (
              ''
            )}
          </Content>
          <Footer style={{ padding: 0, background: '#e5e5e5' }}>
            <GlobalFooter
              copyright={
                <Fragment>
                  <p style={{ marginBottom: ' 2px' }}>
                    Copyright © 2020   上海郦森健康管理咨询有限公司
                  </p>
                  <p>
                    <img style={{ width: '18px', marginBottom: '2px' }} src={transparentP} />
                    工信部备案号：
                    <a href="http://www.miitbeian.gov.cn" target="_blank">
                      沪ICP备19028119号
                    </a>
                  </p>
                </Fragment>
              }
            />
          </Footer>
        </Layout>
      </Layout>
    );

    return (
      <React.Fragment>
        <DocumentTitle title={this.getPageTitle()}>
          <ContainerQuery query={query}>
            {params => <div className={classNames(params)}>{layout}</div>}
          </ContainerQuery>
        </DocumentTitle>
      </React.Fragment>
    );
  }
}

@Form.create()
class ModifyPassword extends PureComponent {
  compareToFirstPassword = (rule, value, callback) => {
    const form = this.props.form;
    if (value && value !== form.getFieldValue('newPwd')) {
      callback('两次输入密码请保持一致！');
    } else {
      callback();
    }
  };

  handleOk = () => {
    const { form, changePwd } = this.props;
    form.validateFields({ force: true }, (err, values) => {
      if (err) return;
      const record = { oldPassword: values.oldPwd, newPassword: values.newPwd };
      changePwd(record);
    });
  };

  render() {
    const { hidePwdModal, showPwd, form } = this.props;
    const { getFieldDecorator } = form;
    return (
      <Modal
        title="修改密码"
        destroyOnClose
        visible={showPwd}
        onCancel={hidePwdModal}
        onOk={this.handleOk}
      >
        <Form layout="inline">
          <Row gutter={{ md: 6, lg: 24, xl: 48 }}>
            <Col md={5} sm={10} />
            <Col md={19} sm={10}>
              <FormItem label="旧密码" style={{ marginLeft: 12 }}>
                {getFieldDecorator('oldPwd', {
                  rules: [
                    {
                      required: true,
                      message: '请输入旧密码！',
                    },
                  ],
                })(<Input style={{ width: '100%' }} type="password" placeholder="" />)}
              </FormItem>
            </Col>
          </Row>
          <Row gutter={{ md: 6, lg: 24, xl: 48 }}>
            <Col md={5} sm={10} />
            <Col md={19} sm={10}>
              <FormItem label="新密码" style={{ marginLeft: 12 }}>
                {getFieldDecorator('newPwd', {
                  rules: [
                    {
                      required: true,
                      message: '请输入新密码！',
                    },
                  ],
                })(<Input style={{ width: '100%' }} type="password" placeholder="" />)}
              </FormItem>
            </Col>
          </Row>
          <Row gutter={{ md: 6, lg: 24, xl: 48 }}>
            <Col md={5} sm={10} />
            <Col md={19} sm={10}>
              <FormItem label="确认密码">
                {getFieldDecorator('confirmPwd', {
                  rules: [
                    {
                      required: true,
                      message: '请重复输入新密码！',
                    },
                    {
                      validator: this.compareToFirstPassword,
                    },
                  ],
                })(<Input style={{ width: '100%' }} type="password" placeholder="" />)}
              </FormItem>
            </Col>
          </Row>
        </Form>
      </Modal>
    );
  }
}
